'''Game server'''

import game_thread 
import game_obj 

class ServerHandler(game_thread.Handler):
    def __init__(self, my_q):
        super(ServerHandler, self).__init__(my_q)
        self.games = dict()
        self.clients = dict()

    def list_games(self):
        return [g for g in self.games]

    def new_game(self, game_id):
        if game_id in self.games:
            raise Exception('A game named %s already exists' % game_id)

        self.games[game_id] = game_obj.Game(game_id, self.update_notify_cb, self.update_specific_client_cb)
        self.notify_game_update()

    def register_client(self, client_name, client_q):
        if client_name in self.clients:
            raise Exception('Client already registered: %s' % client_name)
        
        self.clients[ client_name ] = client_q
        self.notify_game_update(client_q)

    def join_game(self, client_name, game_id, character_choice):
        if game_id not in self.games:
            raise Exception('No game named %s in game list' % game_id)

        if client_name not in self.clients:
            raise Exception('Client not recognized')

        self.games[game_id].add_player( client_name, character_choice)

    def start_game(self, game_id):
        if game_id not in self.games:
            raise Exception('No game named %s in game list' % game_id)
        
        self.games[game_id].start_game()

    def query_house(self, game_id, client_name):
        if game_id not in self.games:
            raise Exception('No game named %s in game list' % game_id)

        self.games[game_id].query_house(client_name)


    def move_player(self, game_id, client_name, character, new_position):

#        print '%s moving player (%s, %s) to %s' % (game_id, client_name, character, repr(new_position))
        
        if game_id not in self.games:
            raise Exception('No game named %s in game list' % game_id)

        self.games[game_id].move_player(client_name, character, new_position)

    def make_suggestion(self, game_id, client_name, sug_character, sug_weapon, sug_room):
        if game_id not in self.games:
            raise Exception('No game named %s in game list' % game_id)

        self.games[game_id].make_suggestion(client_name, sug_character, sug_weapon, sug_room)

    def suggestion_response(self, game_id, client_name, dest_player_id, response):
        if game_id not in self.games:
            raise Exception('No game named %s in game list' % game_id)

        self.games[game_id].suggestion_response(client_name, dest_player_id, response)

    def turn_completed(self, game_id, client_name):
        if game_id not in self.games:
            raise Exception('No game named %s in game list' % game_id)

        self.games[game_id].turn_completed(client_name)

    def make_accusation(self, game_id, player_id, character, weapon, room):
        if game_id not in self.games:
            raise Exception('No game named %s in game list' % game_id)

        self.games[game_id].make_accusation(player_id, character, weapon, room)

    def notify_game_update(self, client_q = None):
        '''Notify all clients whenever a game is added'''
        if client_q is not None:
            game_thread.GameThread.ntfy(client_q, 'game_list_update', self.list_games())
        else:
            for c in self.clients.itervalues():
                game_thread.GameThread.ntfy(c, 'game_list_update', self.list_games())
            



    ## event notification callbacks ##
    def update_notify_cb(self, game_state):
        if game_state.game_id not in self.games:
            raise Exception( 'Whoa!  game_id %s not in games' % game_id)
        
        for player in game_state.players:
            if player.player_id not in self.clients:
                raise Exception( 'Client %s not registered' % repr(player.player_id))
            
            game_thread.GameThread.ntfy(self.clients[ player.player_id ], 'state_update', game_state)
    
    def update_specific_client_cb(self, game_id, client_id, notification, *args):
        if game_id not in self.games:
            raise Exception( 'Whoa!  game_id %s not in games' % game_id)
        
        if client_id not in self.clients:
            raise Exception( 'Whoa!  client_id %s not in clients' % client_id)

        client_q = self.clients[ client_id ]
        game_thread.GameThread.ntfy(client_q, notification, game_id, *args)

class CluelessServer(game_thread.GameThread):
    def __init__(self, name):
        super(CluelessServer, self).__init__('Server: %s' % name, ServerHandler)


if __name__ == '__main__':
    pass
